import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BatchEventsDto, EventDto } from './dto/batch-events.dto';
import { TrackPageviewDto } from './dto/track-pageview.dto';
import { Website } from './entities/website.entity';
// 修复导入路径
import { Event } from './entities/event.entity';
import { Session } from './entities/session.entity';
import { PageView } from './entities/page-view.entity';
import { WebsiteService } from './website.service';
import { StatsService } from './stats.service';
import { IpService } from './ip.service';
import { SessionService } from './session.service';
import { LogService } from './log.service';
import { NotFoundException, Logger } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';

@Injectable()
export class TrackingService {
  private readonly logger = new Logger(TrackingService.name);
  
  constructor(
    private websiteService: WebsiteService,
    private statsService: StatsService,
    private ipService: IpService,
    private sessionService: SessionService,
    private logService: LogService,
    @InjectRepository(PageView)
    private pageViewRepository: Repository<PageView>,
    @InjectRepository(Website)
    private websiteRepository: Repository<Website>,
    @InjectRepository(Event)
    private eventRepository: Repository<Event>,
    @InjectRepository(Session)
    private sessionRepository: Repository<Session>,
  ) {}

  // 网站管理
  createWebsite(dto) { return this.websiteService.createWebsite(dto); }
  updateWebsite(id, dto) { return this.websiteService.updateWebsite(id, dto); }
  deleteWebsite(id) { return this.websiteService.deleteWebsite(id); }
  deleteAllWebsites() { return this.websiteService.deleteAllWebsites(); }
  getAllWebsites() { return this.websiteService.getAllWebsites(); }
  getWebsiteById(id) { return this.websiteService.getWebsiteById(id); }
  getWebsiteByTrackingId(trackingId) { return this.websiteService.getWebsiteByTrackingId(trackingId); }
  getEmbedCode(id) { return this.websiteService.getEmbedCode(id); }

  // 统计
  getWebsiteStats(id, query) { return this.statsService.getWebsiteStats(id, query); }
  getWebsiteSummary(id, query) { return this.statsService.getWebsiteSummary(id, query); }
  getWebsiteTrend(id, query) { return this.statsService.getWebsiteTrend(id, query); }
  
  // IP
  getIpVisits(ip, websiteId, startDate, endDate) { return this.ipService.getIpVisits(ip, websiteId, startDate, endDate); }
  // 获取网站所有访问过的IP
  getWebsiteIps(websiteId) { return this.ipService.getWebsiteIps(websiteId); }

  // 会话
  getSessionDetails(sessionId) { return this.sessionService.getSessionDetails(sessionId); }

  // 日志
  getLogStats() { return this.logService.getLogStats(); }
  getBusinessLoopLogs(trackingId, date) { return this.logService.getBusinessLoopLogs(trackingId, date); }
  checkBusinessLoopIntegrity(trackingId, date) { return this.logService.checkBusinessLoopIntegrity(trackingId, date); }
  
  // 补充：页面访问埋点
  async trackPageview(trackPageviewDto: TrackPageviewDto, ip: string, userAgent: string) {
    // 这里只做最简实现，实际可根据原逻辑补充
    const website = await this.websiteService.getWebsiteByTrackingId(trackPageviewDto.trackingId);
    if (!website) return null;
    
    const pageView = this.pageViewRepository.create({
      websiteId: website.id,
      url: trackPageviewDto.url,
      title: trackPageviewDto.title,
      referrer: trackPageviewDto.referrer,
      ip,
      userAgent,
      sessionId: trackPageviewDto.sessionId,
      customData: trackPageviewDto.customData,
    });
    
    return this.pageViewRepository.save(pageView);
  }

  /**
   * 处理批量事件
   */
  async processBatchEvents(
    batchEventsDto: BatchEventsDto,
    ip: string,
    userAgent: string
  ): Promise<void> {
    // 验证跟踪ID
    const website = await this.websiteRepository.findOne({
      where: { trackingId: batchEventsDto.trackingId, isActive: true }
    });

    if (!website) {
      throw new NotFoundException(`Website with tracking ID ${batchEventsDto.trackingId} not found or inactive`);
    }

    // 处理每个事件
    const processPromises = batchEventsDto.events.map(async (event) => {
      try {
        switch (event.type) {
          case 'pageview':
            await this.processPageViewEvent(event, batchEventsDto, website, ip, userAgent);
            break;
          case 'event':
            await this.processCustomEvent(event, batchEventsDto, website, ip, userAgent);
            break;
          case 'session_end':
            await this.processSessionEndEvent(event, batchEventsDto, website, ip, userAgent);
            break;
          default:
            this.logger.warn(`Unknown event type: ${event.type}`);
        }
      } catch (error) {
        this.logger.error(`Error processing event: ${error.message}`, error.stack);
        // 继续处理其他事件，不中断批处理
      }
    });

    // 等待所有事件处理完成
    await Promise.all(processPromises);
  }

  /**
   * 处理页面访问事件
   */
  private async processPageViewEvent(
    event: EventDto,
    batchEventsDto: BatchEventsDto,
    website: Website,
    ip: string,
    userAgent: string
  ): Promise<void> {
    // 构造页面访问DTO
    const pageviewDto: TrackPageviewDto = {
      trackingId: batchEventsDto.trackingId,
      url: event.customData?.url || batchEventsDto.url,
      title: event.customData?.title || batchEventsDto.title,
      referrer: event.customData?.referrer,
      sessionId: batchEventsDto.sessionId,
      customData: event.customData || {}
    };

    // 使用现有的页面访问处理逻辑
    await this.trackPageview(pageviewDto, ip, userAgent);
  }

  /**
   * 处理自定义事件
   */
  private async processCustomEvent(
    event: EventDto,
    batchEventsDto: BatchEventsDto,
    website: Website,
    ip: string,
    userAgent: string
  ): Promise<void> {
    // 创建事件记录
    const eventRecord = new Event();
    eventRecord.websiteId = website.id;
    eventRecord.sessionId = batchEventsDto.sessionId;
    eventRecord.category = event.category || 'unknown';
    eventRecord.action = event.action || 'unknown';
    eventRecord.label = event.label;
    eventRecord.value = event.value;
    eventRecord.url = event.customData?.url || batchEventsDto.url;
    eventRecord.ip = ip;
    eventRecord.userAgent = userAgent;
    eventRecord.customData = event.customData;
    eventRecord.createdAt = event.timestamp ? new Date(event.timestamp) : new Date();

    // 保存事件
    await this.eventRepository.save(eventRecord);
  }

  /**
   * 处理会话结束事件
   */
  private async processSessionEndEvent(
    event: EventDto,
    batchEventsDto: BatchEventsDto,
    website: Website,
    ip: string,
    userAgent: string
  ): Promise<void> {
    // 查找会话
    const session = await this.sessionRepository.findOne({
      where: { 
        websiteId: website.id,
        sessionId: batchEventsDto.sessionId
      }
    });

    if (session) {
      // 更新会话结束时间和持续时间
      session.endTime = new Date();
      session.duration = batchEventsDto.sessionDuration || 
        (session.endTime.getTime() - session.startTime.getTime());
      
      // 保存更新后的会话
      await this.sessionRepository.save(session);
    }

    // 创建会话结束事件
    const sessionEndEvent = new Event();
    sessionEndEvent.websiteId = website.id;
    sessionEndEvent.sessionId = batchEventsDto.sessionId;
    sessionEndEvent.category = 'session';
    sessionEndEvent.action = 'end';
    sessionEndEvent.value = batchEventsDto.sessionDuration;
    sessionEndEvent.url = batchEventsDto.url;
    sessionEndEvent.ip = ip;
    sessionEndEvent.userAgent = userAgent;
    sessionEndEvent.customData = { sessionDuration: batchEventsDto.sessionDuration };
    sessionEndEvent.createdAt = new Date();

    // 保存事件
    await this.eventRepository.save(sessionEndEvent);
  }

  // 返回埋点脚本
  getTrackingScript(): string {
    try {
      const scriptPath = path.join(__dirname, '..', '..', '..', 'src', 'modules', 'tracking', 'tracking-script.js');
      return fs.readFileSync(scriptPath, 'utf8');
    } catch (error) {
      return 'console.log("DevOps BI tracking script loaded")';
    }
  }
} 